package top.xia17.plugins.fast.base.autoconfiguration;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.filter.FormContentFilter;
import top.xia17.plugins.fast.base.core.Xia17FastProperties;
import top.xia17.plugins.fast.base.cors.CorsProperties;

import java.util.Arrays;

/**
 * xia17fast的基础自动配置
 *
 * @author xia17
 * @since 2022/2/24 16:53
 */
@Configuration
@EnableConfigurationProperties({CorsProperties.class,Xia17FastProperties.class})
@RequiredArgsConstructor
@Slf4j
public class BaseAutoconfiguration {

    private final CorsProperties corsProperties;


    /**
     * 配置跨域请求
     *
     * @return CorsFilter
     */
    @Bean
    @ConditionalOnProperty(
            prefix = "xia17fast.cors",
            name = {"enabled"},
            havingValue = "true",
            matchIfMissing = true
    )
    @ConditionalOnMissingBean(name = "corsFilter")
    public CorsFilter corsFilter() {
        final String allCorsStr = "*";
        // 解析yml 配置文件中的数据
        String[] cors;
        boolean isAll = false;
        String corsStr = corsProperties.getOrigins();
        if (corsStr == null || "".equals(corsStr) || allCorsStr.equals(corsStr)) {
            // 如果没有配置那么允许所有跨域
            cors = new String[]{"*"};
            isAll = true;
        } else {
            cors = StrUtil.splitToArray(corsProperties.getOrigins(), ',');
        }
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        org.springframework.web.cors.CorsConfiguration config = new org.springframework.web.cors.CorsConfiguration();
        config.setAllowCredentials(true);
        // springboot2.4 新的方式
        if (isAll) {
            config.setAllowedOriginPatterns(Arrays.asList(cors));
        } else {
            config.setAllowedOrigins(Arrays.asList(cors));
        }
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        log.info("xia17fast: 项目已开启跨域");
        return new CorsFilter(source);
    }


    /**
     * 添加put，delete等请求方式的form表单参数支持
     *
     * @return /
     */
    @Bean
    @ConditionalOnProperty(
            prefix = "xia17fast",
            name = {"other-req-method-support-form"},
            havingValue = "true",
            matchIfMissing = true
    )
    @ConditionalOnMissingBean(name = "formContentFilter")
    public FormContentFilter formContentFilter() {
        log.info("xia17fast: 添加put，delete等请求方式的form表单参数支持");
        return new FormContentFilter();
    }


    /**
     * 解决JS Long精度丢失问题
     *
     * @return /
     */
    @ConditionalOnProperty(
            prefix = "xia17fast",
            name = {"resp-json-long-to-string"},
            havingValue = "true",
            matchIfMissing = true
    )
    @ConditionalOnMissingBean(name = "jackson2ObjectMapperBuilderCustomizer")
    @Bean("jackson2ObjectMapperBuilderCustomizer")
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        log.info("xia17fast: 开启返回json时Long转String类型功能");
        return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder
                .serializerByType(Long.class, ToStringSerializer.instance)
                .serializerByType(Long.TYPE, ToStringSerializer.instance);
    }



}
